﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Security.Principal;

namespace AuthorizedNavigation.Client
{
    public class UriRightMapping : DependencyObject, AuthorizedNavigation.Client.IUriRightMapping
    {

        public static readonly DependencyProperty UriProperty =
            DependencyProperty.Register("Uri", typeof(Uri), typeof(UriRightMapping), new PropertyMetadata(null));


        public Uri Uri
        {
            get { return (Uri)this.GetValue(UriProperty); }
            set { this.SetValue(UriProperty, value); }
        }


        public static readonly DependencyProperty AuthenticationRequiredProperty =
            DependencyProperty.Register("AuthenticationRequired", typeof(bool), typeof(UriRightMapping), new PropertyMetadata(false));


        public bool AuthenticationRequired
        {
            get { return (bool)this.GetValue(AuthenticationRequiredProperty); }
            set { this.SetValue(AuthenticationRequiredProperty, value); }
        }

        public static readonly DependencyProperty AllowedRolesProperty =
            DependencyProperty.Register("AllowedRoles", typeof(string), typeof(UriRightMapping), new PropertyMetadata(""));

        public string AllowedRoles
        {
            get { return (string)this.GetValue(AllowedRolesProperty); }
            set { 
                this.SetValue(AllowedRolesProperty, value);
                _rolesAsList = value.Split(',').ToList<string>();
                AuthenticationRequired = true;
            }
        }

        private List<string> _rolesAsList = new List<string>();


        public bool CanNavigate(IPrincipal principal)
        {
            // No uri?  
            if (this.Uri == null)
                return false;

            // check authentication
            if (principal == null && AuthenticationRequired)
                return false;
            else if (principal == null && !AuthenticationRequired)
                return true;

            if (!principal.Identity.IsAuthenticated && AuthenticationRequired)
                return false;
            
            // authentication checked.  Now check authorization.

            // check role
            if (_rolesAsList.Count == 0 || _rolesAsList.Contains<string>("Any"))
                return true;

            foreach (var role in _rolesAsList)
            {
                if (principal.IsInRole(role))
                    return true;
            }

            return false;

        }
        
        public bool Matches(System.Uri targetUri)
        {
            return (Uri == targetUri);
        }
    }
}
